package com.ygl.config.core.parser.xml;
import com.ygl.common.constant.DiscoveryConstant;
import com.ygl.common.exception.CoreException;
import com.ygl.common.entity.*;
import com.ygl.common.util.StringUtil;
import com.ygl.config.core.constant.ConfigConstant;
import com.ygl.config.core.parser.CoreConfigParser;
import com.ygl.config.core.parser.xml.dom4j.Dom4JReader;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;


import java.util.*;

/**
 * @Author yanggld
 * @Date 2019/12/13-11:50
 * @Description
 */
@Slf4j
public class XmlConfigParser implements CoreConfigParser {

	@Override
	public RuleEntity parse(String config) {
		try {
			Document document = Dom4JReader.getDocument(config);
			Element rootElement = document.getRootElement();
			RuleEntity ruleEntity = parseRoot(config, rootElement);
			// Just for Json text print
			// System.out.println(JsonUtil.toJson(ruleEntity));
			return ruleEntity;
		} catch (Exception e) {
			log.error("Parse config failed", e);
		}
		return null;
	}

	private RuleEntity parseRoot(String config, Element element) {
		int registerElementCount = element.elements(ConfigConstant.REGISTER_ELEMENT_NAME).size();
		if (registerElementCount > 1) {
			throw new CoreException("Allow only one element[" + ConfigConstant.REGISTER_ELEMENT_NAME + "] to be configed");
		}
		// 服务注册规则
		RegisterEntity registerEntity = null;
		/**
		 * 服务发现规则
		 * 1. 版本匹配
		 * 2. 区域匹配
		 * 3. 版本权重
		 * 4. 区域权重
		 */
		DiscoveryEntity discoveryEntity = null;
		// 路由策略
		StrategyEntity strategyEntity = null;
		// 定制化路由策略
		StrategyCustomizationEntity strategyCustomizationEntity = null;
		for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
			Object childElementObject = elementIterator.next();
			if (childElementObject instanceof Element) {
				Element childElement = (Element) childElementObject;
				if (StringUtils.equals(childElement.getName(), ConfigConstant.REGISTER_ELEMENT_NAME)) {
					registerEntity = new RegisterEntity();
					parseRegister(childElement, registerEntity);
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.DISCOVERY_ELEMENT_NAME)) {
					discoveryEntity = new DiscoveryEntity();
					parseDiscovery(childElement, discoveryEntity);
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.STRATEGY_ELEMENT_NAME)) {
					strategyEntity = new StrategyEntity();
					parseStrategy(childElement, strategyEntity);
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.STRATEGY_CUSTOMIZATION_ELEMENT_NAME)) {
					strategyCustomizationEntity = new StrategyCustomizationEntity();
					parseStrategyCustomization(childElement, strategyCustomizationEntity);
				}
			}
		}
		RuleEntity ruleEntity = new RuleEntity();
		ruleEntity.setRegisterEntity(registerEntity);
		ruleEntity.setDiscoveryEntity(discoveryEntity);
		ruleEntity.setStrategyEntity(strategyEntity);
		ruleEntity.setStrategyCustomizationEntity(strategyCustomizationEntity);
		ruleEntity.setContent(config);
		return ruleEntity;
	}

	/**
	 * 解析服务注册规则
	 * @param element
	 * @param registerEntity
	 */
	private void parseRegister(Element element, RegisterEntity registerEntity) {
		for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
			Object childElementObject = elementIterator.next();
			if (childElementObject instanceof Element) {
				Element childElement = (Element) childElementObject;
				if (StringUtils.equals(childElement.getName(), ConfigConstant.WHITELIST_ELEMENT_NAME)) {
					parseHostFilter(childElement, ConfigConstant.WHITELIST_ELEMENT_NAME, registerEntity);
				}
			}
		}
	}

	/**
	 * 服务注册 主机白名单、黑名单
	 * @param element
	 * @param filterTypeValue
	 * @param registerEntity
	 */
	private void parseHostFilter(Element element, String filterTypeValue, RegisterEntity registerEntity) {
		HostFilterEntity hostFilterEntity = new HostFilterEntity();
		hostFilterEntity.setFilterType(HostFilterType.fromString(filterTypeValue));
		Attribute globalFilterAttribute = element.attribute(ConfigConstant.FILTER_VALUE_ATTRIBUTE_NAME);
		if (globalFilterAttribute != null) {
			String globalFilterValue = globalFilterAttribute.getData().toString().trim();
			List<String> globalFilterValueList = StringUtil.splitToList(globalFilterValue, ConfigConstant.SEPARATE);
			hostFilterEntity.setFilterValueList(globalFilterValueList);
		}
		registerEntity.setHostFilterEntity(hostFilterEntity);
	}

	/**
	 * 解析服务发现规则
	 * @param element
	 * @param discoveryEntity
	 */
	@SuppressWarnings("rawtypes")
	private void parseDiscovery(Element element, DiscoveryEntity discoveryEntity) {
		for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
			Object childElementObject = elementIterator.next();
			if (childElementObject instanceof Element) {
				Element childElement = (Element) childElementObject;
				if (StringUtils.equals(childElement.getName(), ConfigConstant.VERSION_ELEMENT_NAME)) {
					parseVersionFilter(childElement, discoveryEntity);
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.REGION_ELEMENT_NAME)) {
					parseRegionFilter(childElement, discoveryEntity);
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.WEIGHT_ELEMENT_NAME)) {
					parseWeightFilter(childElement, discoveryEntity);
				}
			}
		}
	}

	/**
	 * 解析版本匹配的规则
	 * @param element
	 * @param discoveryEntity
	 */
	private void parseVersionFilter(Element element, DiscoveryEntity discoveryEntity) {
		VersionFilterEntity versionFilterEntity = discoveryEntity.getVersionFilterEntity();
		if (versionFilterEntity != null) {
			throw new CoreException("Allow only one element[" + ConfigConstant.VERSION_ELEMENT_NAME + "] to be configed");
		}
		versionFilterEntity = new VersionFilterEntity();
		/**
		 * key: 服务消费端
		 * value:（列表） 服务消费端+服务消费端版本  对应   服务提供端+服务消费端版本
		 */
		Map<String, List<VersionEntity>> versionEntityMap = versionFilterEntity.getVersionEntityMap();
		for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
			Object childElementObject = elementIterator.next();
			if (childElementObject instanceof Element) {
				Element childElement = (Element) childElementObject;

				if (StringUtils.equals(childElement.getName(), ConfigConstant.SERVICE_ELEMENT_NAME)) {
					VersionEntity versionEntity = new VersionEntity();

					Attribute consumerServiceNameAttribute = childElement.attribute(ConfigConstant.CONSUMER_SERVICE_NAME_ATTRIBUTE_NAME);
					String consumerServiceName = consumerServiceNameAttribute.getData().toString().trim();
					versionEntity.setConsumerServiceName(consumerServiceName);

					Attribute providerServiceNameAttribute = childElement.attribute(ConfigConstant.PROVIDER_SERVICE_NAME_ATTRIBUTE_NAME);
					String providerServiceName = providerServiceNameAttribute.getData().toString().trim();
					versionEntity.setProviderServiceName(providerServiceName);

					Attribute consumerVersionValueAttribute = childElement.attribute(ConfigConstant.CONSUMER_VERSION_VALUE_ATTRIBUTE_NAME);
					if (consumerVersionValueAttribute != null) {
						String consumerVersionValue = consumerVersionValueAttribute.getData().toString().trim();
						List<String> consumerVersionValueList = StringUtil.splitToList(consumerVersionValue, ConfigConstant.SEPARATE);
						versionEntity.setConsumerVersionValueList(consumerVersionValueList);
					}

					Attribute providerVersionValueAttribute = childElement.attribute(ConfigConstant.PROVIDER_VERSION_VALUE_ATTRIBUTE_NAME);
					if (providerVersionValueAttribute != null) {
						String providerVersionValue = providerVersionValueAttribute.getData().toString().trim();
						List<String> providerVersionValueList = StringUtil.splitToList(providerVersionValue, ConfigConstant.SEPARATE);
						versionEntity.setProviderVersionValueList(providerVersionValueList);
					}

					List<VersionEntity> versionEntityList = versionEntityMap.get(consumerServiceName);
					if (versionEntityList == null) {
						versionEntityList = new ArrayList<>();
						versionEntityMap.put(consumerServiceName, versionEntityList);
					}
					versionEntityList.add(versionEntity);
				}
			}
		}
		discoveryEntity.setVersionFilterEntity(versionFilterEntity);
	}

	/**
	 * 解析区域过滤规则
	 * @param element
	 * @param discoveryEntity
	 */
	@SuppressWarnings("rawtypes")
	private void parseRegionFilter(Element element, DiscoveryEntity discoveryEntity) {
		RegionFilterEntity regionFilterEntity = discoveryEntity.getRegionFilterEntity();
		if (regionFilterEntity != null) {
			throw new CoreException("Allow only one element[" + ConfigConstant.REGION_ELEMENT_NAME + "] to be configed");
		}
		regionFilterEntity = new RegionFilterEntity();
		Map<String, List<RegionEntity>> regionEntityMap = regionFilterEntity.getRegionEntityMap();
		for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
			Object childElementObject = elementIterator.next();
			if (childElementObject instanceof Element) {
				Element childElement = (Element) childElementObject;

				if (StringUtils.equals(childElement.getName(), ConfigConstant.SERVICE_ELEMENT_NAME)) {
					RegionEntity regionEntity = new RegionEntity();

					Attribute consumerServiceNameAttribute = childElement.attribute(ConfigConstant.CONSUMER_SERVICE_NAME_ATTRIBUTE_NAME);
					if (consumerServiceNameAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.CONSUMER_SERVICE_NAME_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String consumerServiceName = consumerServiceNameAttribute.getData().toString().trim();
					regionEntity.setConsumerServiceName(consumerServiceName);

					Attribute providerServiceNameAttribute = childElement.attribute(ConfigConstant.PROVIDER_SERVICE_NAME_ATTRIBUTE_NAME);
					if (providerServiceNameAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.PROVIDER_SERVICE_NAME_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String providerServiceName = providerServiceNameAttribute.getData().toString().trim();
					regionEntity.setProviderServiceName(providerServiceName);

					Attribute consumerRegionValueAttribute = childElement.attribute(ConfigConstant.CONSUMER_REGION_VALUE_ATTRIBUTE_NAME);
					if (consumerRegionValueAttribute != null) {
						String consumerRegionValue = consumerRegionValueAttribute.getData().toString().trim();
						List<String> consumerRegionValueList = StringUtil.splitToList(consumerRegionValue, ConfigConstant.SEPARATE);
						regionEntity.setConsumerRegionValueList(consumerRegionValueList);
					}

					Attribute providerRegionValueAttribute = childElement.attribute(ConfigConstant.PROVIDER_REGION_VALUE_ATTRIBUTE_NAME);
					if (providerRegionValueAttribute != null) {
						String providerRegionValue = providerRegionValueAttribute.getData().toString().trim();
						List<String> providerRegionValueList = StringUtil.splitToList(providerRegionValue, ConfigConstant.SEPARATE);
						regionEntity.setProviderRegionValueList(providerRegionValueList);
					}

					List<RegionEntity> regionEntityList = regionEntityMap.get(consumerServiceName);
					if (regionEntityList == null) {
						regionEntityList = new ArrayList<>();
						regionEntityMap.put(consumerServiceName, regionEntityList);
					}

					regionEntityList.add(regionEntity);
				}
			}
		}
		discoveryEntity.setRegionFilterEntity(regionFilterEntity);
	}

	/**
	 * 解析权重匹配规则
	 * @param element
	 * @param discoveryEntity
	 */
	@SuppressWarnings("rawtypes")
	private void parseWeightFilter(Element element, DiscoveryEntity discoveryEntity) {
		WeightFilterEntity weightFilterEntity = discoveryEntity.getWeightFilterEntity();
		if (weightFilterEntity != null) {
			throw new CoreException("Allow only one element[" + ConfigConstant.WEIGHT_ELEMENT_NAME + "] to be configed");
		}
		weightFilterEntity = new WeightFilterEntity();
		Map<String, List<WeightEntity>> versionWeightEntityMap = new LinkedHashMap<String, List<WeightEntity>>();
		List<WeightEntity> versionWeightEntityList = new ArrayList<WeightEntity>();
		weightFilterEntity.setVersionWeightEntityMap(versionWeightEntityMap);
		weightFilterEntity.setVersionWeightEntityList(versionWeightEntityList);

		Map<String, List<WeightEntity>> regionWeightEntityMap = new LinkedHashMap<String, List<WeightEntity>>();
		List<WeightEntity> regionWeightEntityList = new ArrayList<WeightEntity>();
		weightFilterEntity.setRegionWeightEntityMap(regionWeightEntityMap);
		weightFilterEntity.setRegionWeightEntityList(regionWeightEntityList);

		for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
			Object childElementObject = elementIterator.next();
			if (childElementObject instanceof Element) {
				Element childElement = (Element) childElementObject;
				/**
				 * 局部权重配置解析
				 */
				if (StringUtils.equals(childElement.getName(), ConfigConstant.SERVICE_ELEMENT_NAME)) {
					WeightEntity weightEntity = new WeightEntity();

					Attribute typeAttribute = childElement.attribute(ConfigConstant.TYPE_ATTRIBUTE_NAME);
					if (typeAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.TYPE_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String type = typeAttribute.getData().toString().trim();
					WeightType weightType = WeightType.fromString(type);
					weightEntity.setType(weightType);

					Attribute consumerServiceNameAttribute = childElement.attribute(ConfigConstant.CONSUMER_SERVICE_NAME_ATTRIBUTE_NAME);
					String consumerServiceName = null;
					if (consumerServiceNameAttribute != null) {
						consumerServiceName = consumerServiceNameAttribute.getData().toString().trim();
					}
					weightEntity.setConsumerServiceName(consumerServiceName);

					Attribute providerServiceNameAttribute = childElement.attribute(ConfigConstant.PROVIDER_SERVICE_NAME_ATTRIBUTE_NAME);
					if (providerServiceNameAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.PROVIDER_SERVICE_NAME_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String providerServiceName = providerServiceNameAttribute.getData().toString().trim();
					weightEntity.setProviderServiceName(providerServiceName);

					Attribute providerWeightValueAttribute = childElement.attribute(ConfigConstant.PROVIDER_WEIGHT_VALUE_ATTRIBUTE_NAME);
					if (providerWeightValueAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.PROVIDER_WEIGHT_VALUE_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String providerWeightValue = providerWeightValueAttribute.getData().toString().trim();

					WeightEntityWrapper.parseWeightEntity(weightEntity, providerWeightValue);

					if (StringUtils.isNotEmpty(consumerServiceName)) {
						if (weightType == WeightType.VERSION) {
							List<WeightEntity> list = versionWeightEntityMap.get(consumerServiceName);
							if (list == null) {
								list = new ArrayList<WeightEntity>();
								versionWeightEntityMap.put(consumerServiceName, list);
							}

							list.add(weightEntity);
						} else if (weightType == WeightType.REGION) {
							List<WeightEntity> list = regionWeightEntityMap.get(consumerServiceName);
							if (list == null) {
								list = new ArrayList<WeightEntity>();
								regionWeightEntityMap.put(consumerServiceName, list);
							}

							list.add(weightEntity);
						}
					} else {
						if (weightType == WeightType.VERSION) {
							versionWeightEntityList.add(weightEntity);
						} else if (weightType == WeightType.REGION) {
							regionWeightEntityList.add(weightEntity);
						}
					}
					/**
					 * 版本全局权重解析
 					 */
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.VERSION_ELEMENT_NAME)) {
					VersionWeightEntity versionWeightEntity = weightFilterEntity.getVersionWeightEntity();
					if (versionWeightEntity != null) {
						throw new CoreException("Allow only one element[" + ConfigConstant.VERSION_ELEMENT_NAME + "] to be configed");
					}

					versionWeightEntity = new VersionWeightEntity();

					Attribute providerWeightValueAttribute = childElement.attribute(ConfigConstant.PROVIDER_WEIGHT_VALUE_ATTRIBUTE_NAME);
					if (providerWeightValueAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.PROVIDER_WEIGHT_VALUE_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String providerWeightValue = providerWeightValueAttribute.getData().toString().trim();

					WeightEntityWrapper.parseWeightEntity(versionWeightEntity, providerWeightValue);

					weightFilterEntity.setVersionWeightEntity(versionWeightEntity);
					/**
					 * 区域全局权重解析
					 */
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.REGION_ELEMENT_NAME)) {
					RegionWeightEntity regionWeightEntity = weightFilterEntity.getRegionWeightEntity();
					if (regionWeightEntity != null) {
						throw new CoreException("Allow only one element[" + ConfigConstant.REGION_ELEMENT_NAME + "] to be configed");
					}

					regionWeightEntity = new RegionWeightEntity();

					Attribute providerWeightValueAttribute = childElement.attribute(ConfigConstant.PROVIDER_WEIGHT_VALUE_ATTRIBUTE_NAME);
					if (providerWeightValueAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.PROVIDER_WEIGHT_VALUE_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String providerWeightValue = providerWeightValueAttribute.getData().toString().trim();

					WeightEntityWrapper.parseWeightEntity(regionWeightEntity, providerWeightValue);

					weightFilterEntity.setRegionWeightEntity(regionWeightEntity);
				}
			}
		}
		discoveryEntity.setWeightFilterEntity(weightFilterEntity);
	}

	private void parseStrategy(Element element, StrategyEntity strategyEntity) {
		int versionElementCount = element.elements(ConfigConstant.VERSION_ELEMENT_NAME).size();
		if (versionElementCount > 1) {
			throw new CoreException("Allow only one element[" + ConfigConstant.VERSION_ELEMENT_NAME + "] of element[" + ConfigConstant.STRATEGY_ELEMENT_NAME + "] to be configed");
		}
		int regionElementCount = element.elements(ConfigConstant.REGION_ELEMENT_NAME).size();
		if (regionElementCount > 1) {
			throw new CoreException("Allow only one element[" + ConfigConstant.REGION_ELEMENT_NAME + "] of element[" + ConfigConstant.STRATEGY_ELEMENT_NAME + "] to be configed");
		}

		int versionWeightElementCount = element.elements(ConfigConstant.VERSION_WEIGHT_ELEMENT_NAME).size();
		if (versionWeightElementCount > 1) {
			throw new CoreException("Allow only one element[" + ConfigConstant.VERSION_WEIGHT_ELEMENT_NAME + "] of element[" + ConfigConstant.STRATEGY_ELEMENT_NAME + "] to be configed");
		}

		int regionWeightElementCount = element.elements(ConfigConstant.REGION_WEIGHT_ELEMENT_NAME).size();
		if (regionWeightElementCount > 1) {
			throw new CoreException("Allow only one element[" + ConfigConstant.REGION_WEIGHT_ELEMENT_NAME + "] of element[" + ConfigConstant.STRATEGY_ELEMENT_NAME + "] to be configed");
		}

		for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
			Object childElementObject = elementIterator.next();
			if (childElementObject instanceof Element) {
				Element childElement = (Element) childElementObject;

				if (StringUtils.equals(childElement.getName(), ConfigConstant.VERSION_ELEMENT_NAME)) {
					String versionValue = childElement.getTextTrim();
					strategyEntity.setVersionValue(versionValue);
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.REGION_ELEMENT_NAME)) {
					String regionValue = childElement.getTextTrim();
					strategyEntity.setRegionValue(regionValue);
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.VERSION_WEIGHT_ELEMENT_NAME)) {
					String versionWeightValue = childElement.getTextTrim();
					strategyEntity.setVersionWeightValue(versionWeightValue);
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.REGION_WEIGHT_ELEMENT_NAME)) {
					String regionWeightValue = childElement.getTextTrim();
					strategyEntity.setRegionWeightValue(regionWeightValue);
				}
			}
		}
	}

	private void parseStrategyCustomization(Element element, StrategyCustomizationEntity strategyCustomizationEntity) {
		int conditionsElementCount = element.elements(ConfigConstant.CONDITIONS_ELEMENT_NAME).size();
		if (conditionsElementCount > 1) {
			throw new CoreException("Allow only one element[" + ConfigConstant.CONDITIONS_ELEMENT_NAME + "] of element[" + ConfigConstant.STRATEGY_CUSTOMIZATION_ELEMENT_NAME + "] to be configed");
		}

		int routesElementCount = element.elements(ConfigConstant.ROUTES_ELEMENT_NAME).size();
		if (routesElementCount > 1) {
			throw new CoreException("Allow only one element[" + ConfigConstant.ROUTES_ELEMENT_NAME + "] of element[" + ConfigConstant.STRATEGY_CUSTOMIZATION_ELEMENT_NAME + "] to be configed");
		}

		List<StrategyConditionEntity> strategyConditionEntityList = new ArrayList<StrategyConditionEntity>();
		List<StrategyRouteEntity> strategyRouteEntityList = new ArrayList<StrategyRouteEntity>();
		for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
			Object childElementObject = elementIterator.next();
			if (childElementObject instanceof Element) {
				Element childElement = (Element) childElementObject;

				if (StringUtils.equals(childElement.getName(), ConfigConstant.CONDITIONS_ELEMENT_NAME)) {
					parseStrategyCondition(childElement, strategyConditionEntityList);
				} else if (StringUtils.equals(childElement.getName(), ConfigConstant.ROUTES_ELEMENT_NAME)) {
					parseStrategyRoute(childElement, strategyRouteEntityList);
				}
			}
		}
		strategyCustomizationEntity.setStrategyConditionEntityList(strategyConditionEntityList);
		strategyCustomizationEntity.setStrategyRouteEntityList(strategyRouteEntityList);
	}

	private void parseStrategyCondition(Element element, List<StrategyConditionEntity> strategyConditionEntityList) {
		for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
			Object childElementObject = elementIterator.next();
			if (childElementObject instanceof Element) {
				Element childElement = (Element) childElementObject;

				if (StringUtils.equals(childElement.getName(), ConfigConstant.CONDITION_ELEMENT_NAME)) {
					StrategyConditionEntity strategyConditionEntity = new StrategyConditionEntity();

					Attribute idAttribute = childElement.attribute(ConfigConstant.ID_ATTRIBUTE_NAME);
					if (idAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.ID_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String id = idAttribute.getData().toString().trim();
					strategyConditionEntity.setId(id);

					Attribute headerAttribute = childElement.attribute(ConfigConstant.HEADER_ATTRIBUTE_NAME);
					if (headerAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.HEADER_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String header = headerAttribute.getData().toString().trim();
					List<String> headerList = StringUtil.splitToList(header, DiscoveryConstant.SEPARATE);
					for (String value : headerList) {
						String[] valueArray = StringUtils.split(value, DiscoveryConstant.EQUALS);
						String headerName = valueArray[0].trim();
						String headerValue = valueArray[1].trim();

						strategyConditionEntity.getHeaderMap().put(headerName, headerValue);
					}

					Attribute versionIdAttribute = childElement.attribute(ConfigConstant.VERSION_ELEMENT_NAME + DiscoveryConstant.DASH + ConfigConstant.ID_ATTRIBUTE_NAME);
					if (versionIdAttribute != null) {
						String versionId = versionIdAttribute.getData().toString().trim();
						strategyConditionEntity.setVersionId(versionId);
					}

					Attribute regionIdAttribute = childElement.attribute(ConfigConstant.REGION_ELEMENT_NAME + DiscoveryConstant.DASH + ConfigConstant.ID_ATTRIBUTE_NAME);
					if (regionIdAttribute != null) {
						String regionId = regionIdAttribute.getData().toString().trim();
						strategyConditionEntity.setRegionId(regionId);
					}

					Attribute versionWeightIdAttribute = childElement.attribute(ConfigConstant.VERSION_WEIGHT_ELEMENT_NAME + DiscoveryConstant.DASH + ConfigConstant.ID_ATTRIBUTE_NAME);
					if (versionWeightIdAttribute != null) {
						String versionWeightId = versionWeightIdAttribute.getData().toString().trim();
						strategyConditionEntity.setVersionWeightId(versionWeightId);
					}

					Attribute regionWeightIdAttribute = childElement.attribute(ConfigConstant.REGION_WEIGHT_ELEMENT_NAME + DiscoveryConstant.DASH + ConfigConstant.ID_ATTRIBUTE_NAME);
					if (regionWeightIdAttribute != null) {
						String regionWeightId = regionWeightIdAttribute.getData().toString().trim();
						strategyConditionEntity.setRegionWeightId(regionWeightId);
					}

					strategyConditionEntityList.add(strategyConditionEntity);
				}
			}
		}
	}

	private void parseStrategyRoute(Element element, List<StrategyRouteEntity> strategyRouteEntityList) {
		for (Iterator elementIterator = element.elementIterator(); elementIterator.hasNext();) {
			Object childElementObject = elementIterator.next();
			if (childElementObject instanceof Element) {
				Element childElement = (Element) childElementObject;

				if (StringUtils.equals(childElement.getName(), ConfigConstant.ROUTE_ELEMENT_NAME)) {
					StrategyRouteEntity strategyRouteEntity = new StrategyRouteEntity();

					Attribute idAttribute = childElement.attribute(ConfigConstant.ID_ATTRIBUTE_NAME);
					if (idAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.ID_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String id = idAttribute.getData().toString().trim();
					strategyRouteEntity.setId(id);

					Attribute typeAttribute = childElement.attribute(ConfigConstant.TYPE_ATTRIBUTE_NAME);
					if (typeAttribute == null) {
						throw new CoreException("Attribute[" + ConfigConstant.TYPE_ATTRIBUTE_NAME + "] in element[" + childElement.getName() + "] is missing");
					}
					String type = typeAttribute.getData().toString().trim();
					StrategyType strategyType = StrategyType.fromString(type);
					strategyRouteEntity.setType(strategyType);

					String value = childElement.getTextTrim();
					strategyRouteEntity.setValue(value);

					strategyRouteEntityList.add(strategyRouteEntity);
				}
			}
		}
	}

}
